package financeSystem;

import salesSystem.model.Order;
import salesSystem.model.OrderItem;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class FinanceManagementSystem {
    private Map<String, Invoice> invoices = new HashMap<>();
    private Map<String, Payment> payments = new HashMap<>();
    private List<FinancialRecord> financialRecords = new ArrayList<>();
    
    public static void main(String[] args) {
        FinanceManagementSystem financeSystem = new FinanceManagementSystem();
        
        // 模拟从销售系统接收订单
        OrderItem item1 = new OrderItem("P1001", "笔记本电脑", 1, 5999.00);
        OrderItem item2 = new OrderItem("P1002", "无线鼠标", 2, 99.50);
        Order order = new Order("CUST001", List.of(item1, item2), "北京市海淀区中关村大街1号");
        order.setOrderId("ORD20230001");
        order.setOrderDate(LocalDate.now());
        
        System.out.println("=== 财务管理系统启动 ===");
        
        // 1. 生成发票
        Invoice invoice = financeSystem.createInvoice(order);
        System.out.println("生成发票: " + invoice.getInvoiceNumber());
        
        // 2. 记录支付
        Payment payment = financeSystem.recordPayment(order.getOrderId(), 
            order.getTotalAmount(), "支付宝", "PAY123456789");
        System.out.println("记录支付: " + payment.getPaymentId());
        
        // 3. 核对账目
        boolean isBalanced = financeSystem.checkBalance(order.getOrderId());
        System.out.println("账目核对结果: " + (isBalanced ? "平衡" : "不平衡"));
        
        // 4. 生成财务报表
        FinancialReport report = financeSystem.generateDailyReport(LocalDate.now());
        
        System.out.println("\n=== 今日财务报表 ===");
        System.out.println("日期: " + report.getReportDate());
        System.out.printf("总收入: ¥%.2f\n", report.getTotalIncome());
        System.out.printf("总支出: ¥%.2f\n", report.getTotalExpense());
        System.out.printf("净利润: ¥%.2f\n", report.getNetProfit());
        System.out.println("交易笔数: " + report.getTransactionCount());
        
        System.out.println("\n=== 财务管理系统运行结束 ===");
    }
    
    // 生成发票
    public Invoice createInvoice(Order order) {
        String invoiceNumber = "INV" + LocalDate.now().getYear() + 
                             String.format("%06d", invoices.size() + 1);
        Invoice invoice = new Invoice(
            invoiceNumber,
            order.getOrderId(),
            order.getCustomerId(),
            order.getItems(),
            order.getTotalAmount(),
            LocalDate.now(),
            LocalDate.now().plusDays(30) // 30天后到期
        );
        
        invoices.put(order.getOrderId(), invoice);
        financialRecords.add(new FinancialRecord(
            "INVOICE",
            invoiceNumber,
            order.getTotalAmount(),
            LocalDate.now(),
            "销售发票: " + order.getOrderId()
        ));
        
        return invoice;
    }
    
    // 记录支付
    public Payment recordPayment(String orderId, BigDecimal amount, 
                              String paymentMethod, String transactionId) {
        Invoice invoice = invoices.get(orderId);
        if (invoice == null) {
            throw new IllegalArgumentException("未找到订单对应的发票");
        }
        
        String paymentId = "PAY" + System.currentTimeMillis();
        Payment payment = new Payment(
            paymentId,
            orderId,
            invoice.getInvoiceNumber(),
            amount,
            paymentMethod,
            transactionId,
            LocalDate.now()
        );
        
        payments.put(paymentId, payment);
        financialRecords.add(new FinancialRecord(
            "PAYMENT",
            paymentId,
            amount.negate(), // 支出记为负数
            LocalDate.now(),
            "订单支付: " + orderId
        ));
        
        return payment;
    }
    
    // 核对账目
    public boolean checkBalance(String orderId) {
        Invoice invoice = invoices.get(orderId);
        if (invoice == null) return false;
        
        Payment payment = payments.values().stream()
            .filter(p -> p.getOrderId().equals(orderId))
            .findFirst()
            .orElse(null);
        
        if (payment == null) return false;
        
        return invoice.getTotalAmount().compareTo(payment.getAmount()) == 0;
    }
    
    // 生成日报表
    public FinancialReport generateDailyReport(LocalDate date) {
        BigDecimal totalIncome = BigDecimal.ZERO;
        BigDecimal totalExpense = BigDecimal.ZERO;
        int transactionCount = 0;
        
        for (FinancialRecord record : financialRecords) {
            if (record.getRecordDate().equals(date)) {
                if (record.getAmount().compareTo(BigDecimal.ZERO) > 0) {
                    totalIncome = totalIncome.add(record.getAmount());
                } else {
                    totalExpense = totalExpense.add(record.getAmount().abs());
                }
                transactionCount++;
            }
        }
        
        return new FinancialReport(
            date,
            totalIncome,
            totalExpense,
            totalIncome.subtract(totalExpense),
            transactionCount
        );
    }
    
    // 发票类
    public static class Invoice {
        private String invoiceNumber;
        private String orderId;
        private String customerId;
        private List<OrderItem> items;
        private BigDecimal totalAmount;
        private LocalDate issueDate;
        private LocalDate dueDate;
        private boolean isPaid;
        
        public Invoice(String invoiceNumber, String orderId, String customerId, 
                     List<OrderItem> items, BigDecimal totalAmount,
                     LocalDate issueDate, LocalDate dueDate) {
            this.invoiceNumber = invoiceNumber;
            this.orderId = orderId;
            this.customerId = customerId;
            this.items = items;
            this.totalAmount = totalAmount;
            this.issueDate = issueDate;
            this.dueDate = dueDate;
            this.isPaid = false;
        }
        
        // Getter方法
        public String getInvoiceNumber() { return invoiceNumber; }
        public String getOrderId() { return orderId; }
        public String getCustomerId() { return customerId; }
        public List<OrderItem> getItems() { return items; }
        public BigDecimal getTotalAmount() { return totalAmount; }
        public LocalDate getIssueDate() { return issueDate; }
        public LocalDate getDueDate() { return dueDate; }
        public boolean isPaid() { return isPaid; }
        
        public void markAsPaid() { this.isPaid = true; }
    }
    
    // 支付类
    public static class Payment {
        private String paymentId;
        private String orderId;
        private String invoiceNumber;
        private BigDecimal amount;
        private String paymentMethod;
        private String transactionId;
        private LocalDate paymentDate;
        
        public Payment(String paymentId, String orderId, String invoiceNumber,
                      BigDecimal amount, String paymentMethod, 
                      String transactionId, LocalDate paymentDate) {
            this.paymentId = paymentId;
            this.orderId = orderId;
            this.invoiceNumber = invoiceNumber;
            this.amount = amount;
            this.paymentMethod = paymentMethod;
            this.transactionId = transactionId;
            this.paymentDate = paymentDate;
        }
        
        // Getter方法
        public String getPaymentId() { return paymentId; }
        public String getOrderId() { return orderId; }
        public String getInvoiceNumber() { return invoiceNumber; }
        public BigDecimal getAmount() { return amount; }
        public String getPaymentMethod() { return paymentMethod; }
        public String getTransactionId() { return transactionId; }
        public LocalDate getPaymentDate() { return paymentDate; }
    }
    
    // 财务记录类
    public static class FinancialRecord {
        private String recordType; // INVOICE/PAYMENT/EXPENSE etc.
        private String referenceId;
        private BigDecimal amount;
        private LocalDate recordDate;
        private String description;
        
        public FinancialRecord(String recordType, String referenceId,
                             BigDecimal amount, LocalDate recordDate,
                             String description) {
            this.recordType = recordType;
            this.referenceId = referenceId;
            this.amount = amount;
            this.recordDate = recordDate;
            this.description = description;
        }
        
        // Getter方法
        public String getRecordType() { return recordType; }
        public String getReferenceId() { return referenceId; }
        public BigDecimal getAmount() { return amount; }
        public LocalDate getRecordDate() { return recordDate; }
        public String getDescription() { return description; }
    }
    
    // 财务报表类
    public static class FinancialReport {
        private LocalDate reportDate;
        private BigDecimal totalIncome;
        private BigDecimal totalExpense;
        private BigDecimal netProfit;
        private int transactionCount;
        
        public FinancialReport(LocalDate reportDate, BigDecimal totalIncome,
                             BigDecimal totalExpense, BigDecimal netProfit,
                             int transactionCount) {
            this.reportDate = reportDate;
            this.totalIncome = totalIncome;
            this.totalExpense = totalExpense;
            this.netProfit = netProfit;
            this.transactionCount = transactionCount;
        }
        
        // Getter方法
        public LocalDate getReportDate() { return reportDate; }
        public BigDecimal getTotalIncome() { return totalIncome; }
        public BigDecimal getTotalExpense() { return totalExpense; }
        public BigDecimal getNetProfit() { return netProfit; }
        public int getTransactionCount() { return transactionCount; }
    }
}